import axios from 'axios';
import {ElNotification, ElMessageBox} from 'element-plus';
import sysConfig from "@/config";
import tool from '@/utils/tool';
import router from '@/router';
import jsFileDownload from 'js-file-download'

axios.defaults.baseURL = ''
axios.defaults.timeout = sysConfig.TIMEOUT
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.cookie.get("TOKEN");
		if (token) {
			config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
		}
		if (!sysConfig.REQUEST_CACHE && config.method == 'get') {
			config.params = config.params || {};
			config.params['_'] = new Date().getTime();
		}
		Object.assign(config.headers, sysConfig.HEADERS)
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);

// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {
		if (response.data.status == 401) {
			//此处可用于oauth2.0的单点登陆用户身份的判断。并进行跳转。
			router.replace({path: '/login'});
		} else {
			return response;
		}
	},
	(error) => {
		if (error.response) {
			if (error.response.status == 404) {
				ElNotification.error({
					title: '请求错误',
					message: "Status:404，正在请求不存在的服务器记录！"
				});
			} else if (error.response.status == 500) {
				ElNotification.error({
					title: '请求错误',
					message: error.response.data.message || "Status:500，服务器发生错误！"
				});
			} else if (error.response.status == 401 || error.response.status == 400) {
				ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
					type: 'error',
					closeOnClickModal: false,
					center: true,
					confirmButtonText: '重新登录'
				}).then(() => {
					router.replace({path: '/login'});
				}).catch(() => {
				})
			} else {
				ElNotification.error({
					title: '请求错误',
					message: error.message || `Status:${error.response.status}，未知错误！`
				});
			}
		} else {
			ElNotification.error({
				title: '请求错误',
				message: "请求服务器无响应！"
			});
		}

		return Promise.reject(error.response);
	}
);

var http = {

	/** get 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	get: function (url, data = {}, config = {}) {

		return new Promise((resolve, reject) => {
			let params = {};
			console.log(data)
			if (data != null) {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					Object.keys(data).forEach((key) => {
						if (data[key] instanceof Array) {
							params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
						} else if (data[key] instanceof Object) {
							params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
						} else {
							params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
						}
					})
				} else {
					Object.keys(data).forEach((key) => {
						console.log('data',data)
						console.log('data',data[key])
						if (data[key] instanceof Array) {
							params[key + "[]"] = data[key].join(",");
						} else if (data[key] instanceof Object) {
							params[key] = JSON.stringify(data[key]);
						} else {
							params[key] = data[key];
						}
					})
				}
			}
			axios({
				method: 'get',
				url: url,
				params: params,
				...config
			}).then((response) => {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					// resolve(response.data);
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				} else {
					resolve(response.data);
				}
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/**
	 * 文件下载
	 * @param url
	 * @param searchForm
	 */
	fileDownload: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			config = {headers: {'Content-Type': 'application/json;charset=UTF-8'}};
			let params = {};
			if (data != null) {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					Object.keys(data).forEach((key) => {
						if (data[key] instanceof Array) {
							params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
						} else if (data[key] instanceof Object) {
							params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
						} else {
							params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
						}
					})
				} else {
					Object.keys(data).forEach((key) => {
						if (data[key] instanceof Array) {
							params[key + "[]"] = data[key].join(",");
						} else if (data[key] instanceof Object) {
							params[key] = JSON.stringify(data[key]);
						} else {
							params[key] = data[key];
						}
					})
				}
			}
			axios({
				method: 'post',
				url: url,
				params: params,
				responseType: 'blob',
				...config
			}).then((response) => {
				jsFileDownload(response.data, decodeURIComponent(response.headers['filename']))
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** post 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			if (sysConfig.SM4_PRIVATE_KEY != '') {
				let params = {};
				if (data != null) {
					Object.keys(data).forEach((key) => {
						if (data[key] instanceof Array) {
							params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
						} else if (data[key] instanceof Object) {
							params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
						} else {
							params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
						}
					})
				}
				config = {headers: {'Content-Type': 'application/json;charset=UTF-8'}};

				console.log('response11111',config)

				axios({
					method: 'post',
					url: url,
					data: params,
					...config
				}).then((response) => {
					console.log('response2222',response)
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				}).catch((error) => {
					reject(error);
				})
			} else {
				let formData = new FormData();
				if (data != null) {
					Object.keys(data).forEach((key) => {
						if (Array.isArray(data[key])) {
							data[key].forEach(val => {
								formData.append(key + "[]", val);
							})
						} else {
							if (typeof (data[key]) == "object") {
								formData.append(key, JSON.stringify(data[key]));
							} else {
								formData.append(key, data[key]);
							}
						}
					});
				}
				axios({
					method: 'post',
					url: url,
					data: formData,
					...config
				}).then((response) => {
					console.log('response.data', response.data);
					resolve(response.data);
				}).catch((error) => {
					reject(error);
				})
			}
		})
	},
	postPro: function (url, data = {}, config = {}) {
		return axios.post(url, JSON.stringify(data), { // 关键修改点
			...config,
			headers: {
				'Content-Type': 'application/json', // 强制指定JSON格式
				...config.headers
			}
		});
	},
	// postPro: function (url, data = {}, config = {}) {
	// 	return new Promise((resolve, reject) => {
	// 			let formData = new FormData();
	// 			if (data != null) {
	// 				Object.keys(data).forEach((key) => {
	// 					if (Array.isArray(data[key])) {
	// 						data[key].forEach(val => {
	// 							formData.append(key + "[]", val);
	// 						})
	// 					} else {
	// 						if (typeof (data[key]) == "object") {
	// 							formData.append(key, JSON.stringify(data[key]));
	// 						} else {
	// 							formData.append(key, data[key]);
	// 						}
	// 					}
	// 				});
	// 			}
	// 			axios({
	// 				method: 'post',
	// 				url: url,
	// 				data: formData,
	// 				...config
	// 			}).then((response) => {
	// 				console.log('response.data', response.data);
	// 				resolve(response.data);
	// 			}).catch((error) => {
	// 				reject(error);
	// 			})
	// 	})
	// },

	bigPost: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			if (sysConfig.SM4_PRIVATE_KEY != '') {
				let params = {};
				if (data != null) {
					let keys = Object.keys(data)
					keys.forEach(key => {
						if (data[key] instanceof Array) {
							params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
						} else if (data[key] instanceof Object) {
							params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
						} else {
							params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "")
						}
					})
				}
				config = {headers: {'Content-Type': 'application/json;charset=UTF-8'}};
				axios.post(url, params, config).then(response => {
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				}).catch(function (error) {
					reject(error);
				});
			} else {
				config = {headers: {'Content-Type': 'multipart/form-data'}};
				let formData = new FormData();
				if (data != null) {
					Object.keys(data).forEach((key) => {
						if (Array.isArray(data[key])) {
							data[key].forEach(val => {
								formData.append(key + "[]", val);
							})
						} else {
							if (typeof (data[key]) == "object") {
								formData.append(key, JSON.stringify(data[key]));
							} else {
								formData.append(key, data[key]);
							}
						}
					});
				}
				axios({
					method: 'post',
					url: url,
					data: formData,
					...config
				}).then((response) => {
					resolve(response.data);
				}).catch((error) => {
					reject(error);
				})
			}
		})
	},


//由于大文件采用的是form/data 二进制流上传，无需进行参数加密。
	postFile: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},
//----------------------------------------下以功能定义未在本系统中使用无需关心，此处只作为功能扩展-----------------------------------------
	/** put 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	put: function (url, data = {}, config = {}) {
		let params = {};
		if (sysConfig.SM4_PRIVATE_KEY != '') {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
					} else if (data[key] instanceof Object) {
						params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
					} else {
						params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
					}
				})
			}
		} else {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = data[key].join(",");
					} else if (data[key] instanceof Object) {
						params[key] = JSON.stringify(data[key]);
					} else {
						params[key] = data[key];
					}
				})
			}
		}
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url: url,
				data: params,
				...config
			}).then((response) => {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				} else {
					resolve(response.data);
				}
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** patch 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	patch: function (url, data = {}, config = {}) {
		let params = {};
		if (sysConfig.SM4_PRIVATE_KEY != '') {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
					} else if (data[key] instanceof Object) {
						params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
					} else {
						params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
					}
				})
			}
		} else {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = data[key].join(",");
					} else if (data[key] instanceof Object) {
						params[key] = JSON.stringify(data[key]);
					} else {
						params[key] = data[key];
					}
				})
			}
		}
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url: url,
				data: params,
				...config
			}).then((response) => {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				} else {
					resolve(response.data);
				}
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** delete 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	delete: function (url, data = {}, config = {}) {
		let params = {};
		if (sysConfig.SM4_PRIVATE_KEY != '') {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = tool.crypto.createParam(data[key].join(","));
					} else if (data[key] instanceof Object) {
						params[key] = tool.crypto.createParam(JSON.stringify(data[key]));
					} else {
						params[key] = tool.crypto.createParam(data[key] == null ? "" : data[key] + "");
					}
				})
			}
		} else {
			if (data != null) {
				Object.keys(data).forEach((key) => {
					if (data[key] instanceof Array) {
						params[key + "[]"] = data[key].join(",");
					} else if (data[key] instanceof Object) {
						params[key] = JSON.stringify(data[key]);
					} else {
						params[key] = data[key];
					}
				})
			}
		}
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				data: params,
				...config
			}).then((response) => {
				if (sysConfig.SM4_PRIVATE_KEY != '') {
					resolve(JSON.parse(tool.crypto.convertResult(response.data)));
				} else {
					resolve(response.data);
				}
			}).catch((error) => {
				reject(error);
			})
		})
	},
	del: function (url, data = {}, config = {}) {
		// 方案一：通过URL查询参数传递
		const params = new URLSearchParams();
		Object.keys(data).forEach(key => params.append(key, data[key]));

		return axios({
			method: 'delete',
			url: url,
			params: params,  // 查询参数
			...config
		});
	},
	/** jsonp 请求
	 * @param  {接口地址} url
	 * @param  {JSONP回调函数名称} name
	 */
	jsonp: function (url, name = 'jsonp') {
		return new Promise((resolve) => {
			var script = document.createElement('script')
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] = (response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name];
				} catch (e) {
					window[name] = undefined;
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}

export default http;
